{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Map plots\n",
    "\n",
    "Plots on Mapbox maps are available only considering you have a Mapbox account and a Mapbox Access Token. After getting a mabox token it can be written set to pandapower as the following (where `'<token>'` needs to be replaced with provided mapbox token)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-11-25T12:58:56.535646Z",
     "start_time": "2025-11-25T12:58:52.501310Z"
    }
   },
   "outputs": [],
   "source": [
    "from pandapower.plotting.plotly import simple_plotly, pf_res_plotly\n",
    "from pandapower.networks import mv_oberrhein\n",
    "from pandapower.plotting import convert_crs\n",
    "\n",
    "# Prevent Dark Background on plots\n",
    "import plotly.io as pio\n",
    "pio.templates.default = \"plotly_white\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If network geodata are in Geographic coordinate system as latitude/longitude, a network can be plot on different maps.\n",
    "Moreover, if network geodata are not in latitude/longitude, but in some of the projections, it may be converted to lat/long by providing name of the projection (in the form '*epsg:projection_number*'according to http://spatialreference.org/ref/epsg/).  \n",
    "  \n",
    "Following example shows plot of the network mv_oberrhein, where network geodata are in Gauss-Kruger projection (zone 3).  \n",
    "Since geodata are not in lat/long, plot using only `on_map=True` cannot be realized on a map:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-11-25T12:58:59.888794Z",
     "start_time": "2025-11-25T12:58:56.542443Z"
    }
   },
   "outputs": [],
   "source": [
    "net = mv_oberrhein()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The plot can be obtained if one knows specific projection and zone. In this case it is 3-degree Gauss-Kruger zone 3, which corresponds to [epsg:31467](http://spatialreference.org/ref/epsg/31467/):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-11-25T12:59:01.798915Z",
     "start_time": "2025-11-25T12:58:59.986519Z"
    }
   },
   "outputs": [],
   "source": [
    "simple_plotly(net, on_map=True);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Transforming geo-data from a projection to WGS84 (lat/long)\n",
    "There is a function available in pandapower which uses `pyproj` to transform geodata from a projection to WGS84 (lat/long). It transforms and replaces `net.bus.geo` and `net.line.geo` (if existing). An example for `mv_oberreihn`: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-11-25T12:59:02.703662Z",
     "start_time": "2025-11-25T12:59:01.981718Z"
    }
   },
   "outputs": [],
   "source": [
    "net = mv_oberrhein()\n",
    "# since mv_oberrhein is by default in wgs84 we will convert it to Gauss Krüger Zone3 first.\n",
    "convert_crs(net, epsg_in=4326, epsg_out=31467)\n",
    "print('before:\\n', net.bus.geo.head())\n",
    "\n",
    "convert_crs(net, epsg_in=31467, epsg_out=4326)\n",
    "print('\\nafter:\\n', net.bus.geo.head())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Some more map plots..."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The following map styles are available:\n",
    "* 'basic'\n",
    "* 'carto-darkmatter'\n",
    "* 'carto-darkmatter-nolabels'\n",
    "* 'carto-positron'\n",
    "* 'carto-positron-nolabels'\n",
    "* 'carto-voyager'\n",
    "* 'carto-voyager-nolabels'\n",
    "* 'dark'\n",
    "* 'light'\n",
    "* 'open-street-map'\n",
    "* 'outdoors'           \n",
    "* 'satellite''\n",
    "* 'satellite-streets'\n",
    "* 'streets'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-11-25T12:59:03.252508Z",
     "start_time": "2025-11-25T12:59:02.759630Z"
    }
   },
   "outputs": [],
   "source": [
    "simple_plotly(net, on_map=True, map_style='satellite');"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-11-25T12:59:04.233667Z",
     "start_time": "2025-11-25T12:59:03.457965Z"
    }
   },
   "outputs": [],
   "source": [
    "simple_plotly(net, on_map=True, map_style='streets');"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-11-25T12:59:05.231330Z",
     "start_time": "2025-11-25T12:59:04.446773Z"
    }
   },
   "outputs": [],
   "source": [
    "pf_res_plotly(net, on_map=True, map_style='dark', zoomlevel=10);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "More tutorials about interactive plots using ploltly:\n",
    "* [built-in interactive plots](http://nbviewer.jupyter.org/github/e2nIEE/pandapower/blob/develop/tutorials/plotly_built-in.ipynb)\n",
    "* [custom interactive plots](http://nbviewer.jupyter.org/github/e2nIEE/pandapower/blob/develop/tutorials/plotly_traces.ipynb)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
